package com.bupt.vueblog.controller;

import com.bupt.vueblog.constant.Result;
import com.bupt.vueblog.constant.Status;
import com.bupt.vueblog.domain.dto.ArticleInsertDTO;
import com.bupt.vueblog.domain.dto.ArticleSelectDTO;
import com.bupt.vueblog.domain.dto.DetailInfoDTO;
import com.bupt.vueblog.domain.entity.Relation;
import com.bupt.vueblog.domain.dto.ArticleUpdateDTO;
import com.bupt.vueblog.domain.vo.AllArticleVO;
import com.bupt.vueblog.domain.vo.BriefArticleVO;
import com.bupt.vueblog.domain.vo.DetailArticleVO;
import com.bupt.vueblog.service.ArticleService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author 谭继好
 * @Description
 * @date 2024-04-09 20:23
 */
@RestController
@RequestMapping("/article")
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    // 大多数查询都应该携带用户ID，以便查出来用户是否点赞。
    // 同时返回BriefArticleVO，携带用户是否点赞以及收藏

    @GetMapping("/all/{userId}")
    public Result<BriefArticleVO> getAll(@PathVariable int userId) {
        List<BriefArticleVO> allBrief = articleService.getAllBrief(userId);
        return Result.success(allBrief);
    }

    @GetMapping("/user/{userId}")
    public Result<BriefArticleVO> getByUser(@PathVariable int userId) {
        List<BriefArticleVO> res = articleService.getBriefByUser(userId);
        return Result.success(res);
    }

    @GetMapping("/title/{userId}")
    // 根据标题模糊查询，type = 0表示没有筛选条件，type = 1表示我发表的
    // type = 2表示回收站中的博客
    public Result<BriefArticleVO> getByTitle(@Param("title") String title, @PathVariable int userId, @Param("type") Integer type) {
        ArticleSelectDTO data = new ArticleSelectDTO(userId, title, type);
        List<BriefArticleVO> res = articleService.getBriefByTitle(data);
        return Result.success(res);
    }

    @GetMapping("/title/like/{userId}")
    // 根据标题模糊查询我点赞的博客，由于要连表查询，无法合并
    public Result<BriefArticleVO> getByTitleLike(@Param("title") String title, @PathVariable int userId) {
        DetailInfoDTO data = new DetailInfoDTO(userId, title);
        List<BriefArticleVO> res = articleService.getByTitleLike(data);
        return Result.success(res);
    }

    @GetMapping("/title/collect/{userId}")
    // 根据标题模糊查询我收藏的博客，同理
    public Result<BriefArticleVO> getByTitleCollect(@Param("title") String title, @PathVariable int userId) {
        DetailInfoDTO data = new DetailInfoDTO(userId, title);
        List<BriefArticleVO> res = articleService.getByTitleCollect(data);
        return Result.success(res);
    }

    @GetMapping("/username/{userId}")
    // 根据用户名模糊查询
    public Result<BriefArticleVO> getByUsername(@Param("username") String username, @PathVariable int userId) {
        DetailInfoDTO data = new DetailInfoDTO(userId, username);
        List<BriefArticleVO> res = articleService.getByUserName(data);
        return Result.success(res);
    }

    @GetMapping("/deleted/{userId}")
    public Result<BriefArticleVO> getDeleted(@PathVariable int userId) {
        List<BriefArticleVO> res = articleService.getDeleted(userId);
        return Result.success(res);
    }

    @GetMapping("/like/{userId}")
    public Result<BriefArticleVO> getLike(@PathVariable int userId) {
        List<BriefArticleVO> res = articleService.getLikeByUser(userId);
        return Result.success(res);
    }

    @GetMapping("/collect/{userId}")
    public Result<BriefArticleVO> getCollect(@PathVariable int userId) {
        List<BriefArticleVO> res = articleService.getCollectByUser(userId);
        return Result.success(res);
    }

    @GetMapping("/detailAll/{userId}/{articleId}")
    // 查询出博客的所有数据，包括简要博客和具体博客的全部信息
    public Result<AllArticleVO> getAllDetail(@PathVariable Integer userId, @PathVariable("articleId") Integer articleId) {
        AllArticleVO res = articleService.getAllDetail(userId, articleId);
        return Result.success(res);
    }

    @GetMapping("/detail/{articleId}")
    // 用于修改博客时获取初始值，这里只传过来对应的ID，查询出标题及内容
    public Result<DetailArticleVO> getDetail(@PathVariable Integer articleId) {
        DetailArticleVO res = articleService.getUpdateDetail(articleId);
        return Result.success(res);
    }

    @PostMapping
    // 只携带必要信息，更新时间由后端构造
    public Result insert(@RequestBody ArticleInsertDTO data) {
        data.setUpdateTime(LocalDateTime.now());
        articleService.insert(data);
        return Result.success();
    }

    @PutMapping("/detail")
    public Result changeDetail(@RequestBody ArticleUpdateDTO data) {
        articleService.changeDetail(data);
        return Result.success();
    }

    // 点赞或收藏不弹窗显示信息。增加与删除要分开写，因为调用dao层方法不同
    // 前端只需要调用不同接口即可，数据不用携带type，后端设置

    @PutMapping("/addLike")
    public Result addNum(@RequestBody Relation data) {
        data.setType(Status.ARTICLE_LIKE);
        articleService.addNum(data);
        return Result.success();
    }

    @PutMapping("/subLike")
    public Result subNum(@RequestBody Relation data) {
        data.setType(Status.ARTICLE_LIKE);
        articleService.subNum(data);
        return Result.success();
    }

    @PutMapping("/addCollect")
    public Result addCollect(@RequestBody Relation data) {
        data.setType(Status.ARTICLE_COLLECT);
        articleService.addNum(data);
        return Result.success();
    }

    @PutMapping("/subCollect")
    public Result subCollect(@RequestBody Relation data) {
        data.setType(Status.ARTICLE_COLLECT);
        articleService.subNum(data);
        return Result.success();
    }

    @PutMapping("/{id}")
    // 普通删除就是修改标志位隐藏，便于后续恢复
    public Result hide(@PathVariable int id) {
        articleService.hide(id);
        return Result.success();
    }

    @PutMapping("/recover/{articleId}")
    // 恢复隐藏的博客
    public Result recover(@PathVariable int articleId) {
        articleService.recover(articleId);
        return Result.success();
    }


    @DeleteMapping("/{articleId}")
    // 彻底删除对应的博客
    public Result delete(@PathVariable Integer articleId) {
        articleService.delete(articleId);
        return Result.success();
    }
}
